package de.homelabs.moonrat.context.plugin.content;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.bind.ServletRequestUtils;

import de.homelabs.moonrat.config.MoonratConfigurationManager;
import de.homelabs.moonrat.exception.MoonratErrorCode;
import de.homelabs.moonrat.exception.MoonratException;
import de.homelabs.moonrat.metadata.MetaDataParser;
import de.homelabs.moonrat.metadata.MoonratPageMetaData;
import de.homelabs.moonrat.page.MoonratContentSection;
import de.homelabs.moonrat.page.MoonratPageManager;
import de.homelabs.moonrat.util.MoonratWebUtils;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

public class ContentFileSystemDataProvider implements IContentDataProvider {

	static Logger logger = Logger.getLogger(MoonratPageManager.class);
	static final String VERSION = "0.1";
	static final String PROVIDERKEY = "content_data_provider";
	static final String DATAPROVIDERNAME = "contentFileSystemDataProvider";
	
	private Configuration freemarkerConfig = new Configuration();
	
	@Autowired
	private MoonratConfigurationManager mRCfgManager;
	
	public ContentFileSystemDataProvider(){
		System.out.println("ContentFileSystemDataProvider initialized");
	}
	
	/*
	 * (non-Javadoc)
	 * @see de.homelabs.moonrat.context.IDataProvider#getVersion()
	 */
	public String getVersion() {
		return VERSION;
	}

	/*
	 * (non-Javadoc)
	 * @see de.homelabs.moonrat.context.IDataProvider#getProviderKey()
	 */
	public String getProviderKey() {
		return PROVIDERKEY;
	}

	/*
	 * (non-Javadoc)
	 * @see de.homelabs.moonrat.context.plugin.content.IContentDataProvider#getContentByPageUrl(javax.servlet.http.HttpServletRequest)
	 */
	public MoonratContentSection getContentByPageUrl(HttpServletRequest request) throws MoonratException {
		String fileName = null;
		StringBuffer pageContent = new StringBuffer();
		Template template = null;
		String templateContent = null;
		Map<String, Object> contentModel = new HashMap<String, Object>();
		String domain = null;
		String contentPath = null;
		String infoMessage = null;
		MoonratPageMetaData metaData = null;
		
		try {
			//data from request
			infoMessage = ServletRequestUtils.getStringParameter(request, "infoMessage", null);
			
			//domain
			domain = MoonratWebUtils.getDomainFromRequest(request);
			
			//set content path
			//TODO: predefine, perhaps per domain
			contentPath = mRCfgManager.getConfig().getRootPath() + "/" + domain ;
			freemarkerConfig.setDirectoryForTemplateLoading(new File(contentPath));
		
			//build default model
			contentModel = getDefaultPageModel(contentModel);
		
			//get fileName
			fileName = getFileNameFromRequest(request);
		
			//read file
			template = freemarkerConfig.getTemplate("/pages"+fileName);
			
			//process and getContent
			templateContent = FreeMarkerTemplateUtils.processTemplateIntoString(template, contentModel);
		
			//read metadata and replace marker
			metaData = MetaDataParser.parseMetaData(templateContent);
						
			//bind plugins
			
			//build pageContent
			if (infoMessage != null){
				pageContent.append("<span style='color:blue'>" + infoMessage + "</span>");
			}
			
			pageContent.append(templateContent);
			
		} catch (IOException e){
			throw new MoonratException(MoonratErrorCode.TEMPLATE_NOT_FOUND, fileName);
		} catch (TemplateException e) {
			throw new MoonratException(MoonratErrorCode.PROCESSING_TEMPLATE_FAILED, fileName);
		}
		//return
		return new MoonratContentSection(pageContent,0, metaData);
	}

	public File getMediaFileByRequest(HttpServletRequest request) throws MoonratException{
		//domain
		String domain = MoonratWebUtils.getDomainFromRequest(request);
		
		//path to domain scripts
		String contentPath = mRCfgManager.getConfig().getRootPath() + "/" + domain + "/media/scripts";
		
		//get file
		logger.debug("Loading Media File: "+ contentPath + request.getPathInfo());
		File file = new File(contentPath + request.getPathInfo());
		if (file.exists()){
			//Return
			return file;
		} else {
			throw new MoonratException(MoonratErrorCode.MEDIA_FILE_NOT_FOUND);
		}
	}
	
	/**
	 * try to extract a suitable file from the requested uri 
	 * @param HttpServletRequest
	 * @return String
	 */
	private String getFileNameFromRequest(HttpServletRequest request) {
		logger.debug("uri: "+request.getPathInfo());
		String fileName = request.getPathInfo();
		
		//replace suffix
		fileName = fileName.replaceAll(".html|.htm", ".txt");

		//ensure we have the .txt suffix
		if (!fileName.endsWith(".txt")){
			fileName += ".txt";
		}
		
		//urls without page part (missing [name].htm) get mapped to index.html
		if (fileName.endsWith("/.txt"))
			fileName = fileName.replace("/.txt", "/index.html");
		
		//return
		return fileName;
	}
	
	/**
	 * builds the default page model
	 * @param model
	 * @return
	 */
	private Map<String, Object> getDefaultPageModel(Map<String, Object> model){
		return model;
	}

	@Override
	public String getProviderName() {
		return DATAPROVIDERNAME;
	}
}
